package org.lizar.ioc.module;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;

import org.lizar.ioc.Cell;
import org.lizar.ioc.Container;
import org.lizar.log.Log;
import org.lizar.log.Logger;

abstract public class Module implements Cell {
	
	private Log log=Logger.newInstance(this.getClass());
	
	public abstract void init_component()throws Exception;
	
	/**
	 * 
	 * 根据传入的父类Class，返回该类型所有的子类单例对象
	 * 
	 * 工厂类抽象的提供者
	 * 
	 * 如果你有一个工厂类，生产一类叫video的东西。
	 * 
	 * video包含了很多种，YoukuVideo，TuDouVideo，KaixinVideo... ... etc..
	 * 
	 * 那么他们的父类接口Video只需要继承接口Cell
	 * 
	 * 然后再通过本方法，就能够获得所有Video接口的实例
	 * 
	 * YoukuVideo，TuDouVideo，KaixinVideo 都为单例模式
	 * 
	 * 本方法返回的对象都是以单例形式
	 * 
	 * */
	 public  <T> List<T> getSubCells(Class<T> t){
			List<T> list=new LinkedList<T>();
			for(Entry<String,Cell> entry:Container.getAll().entrySet()){
				try{
					entry.getValue().getClass().asSubclass(t);
				}catch(Exception e){
					continue;
				}
				list.add((T)entry.getValue());
			}
			return list;
	}

	/**
	 * 
	 * 根据传入的父类Class，返回该类型所有的子类新实例化对象
	 * 
	 * 工厂类抽象的提供者
	 * 
	 * 如果你有一个工厂类，生产一类叫video的东西。
	 * 
	 * video包含了很多种，YoukuVideo，TuDouVideo，KaixinVideo... ... etc..
	 * 
	 * 那么他们的父类接口Video只需要继承接口Cell
	 * 
	 * 然后再通过本方法，就能够获得所有Video接口的实例
	 * 
	 * YoukuVideo，TuDouVideo，KaixinVideo 都为单例模式
	 * 
	 * 本方法返回的对象都是以单例形式
	 * 
	 * */
	 public  <T> List<T> getNewSubCells(Class<T> t){
	    	List<T> list=getSubCells(t);
	    	List<T> instance_list=new ArrayList<T>(list.size());
	    	for(T o:list){
	    		instance_list.add(getNewCell(t));
	    		
	    	}
	    	return instance_list;
	 }
	
	
	    

	public  <T> T getNewCell(Class<T> t){
	    	T o;
	    	try {
	    		o=t.newInstance();
			} catch (Exception e) {
				String err_msg="been:"+t.getName()+" 不能被实例化，Lizar IOC实例化对象只支持默认构造器结合init_property方法自动实现";
				log.error(err_msg,e);
				throw new RuntimeException(err_msg,e);
			}
	    	try{
	    		t.asSubclass(Cell.class);
	    	}catch(Exception e){
	    		return o;
	    	}
	    	Cell c=(Cell)o;
	    	try {
				c.init_property();
			} catch (Exception e) {
				e.printStackTrace();
				String err_msg="been:"+t.getName()+" 实例化失败";
				throw new RuntimeException(err_msg,e);
			}
	    	return o;
	}
	    
	   
	    
}
